
//Eli Elder
//adventurer random test


#include "dominion.h"
#include "dominion_helpers.h"
#include <string.h>
#include <stdio.h>
#include <stdlib.h> 
#include <assert.h>
#include <math.h>
#include "rngs.h"
#include <time.h>

//set PRINTOUT to 0 to remove printfs out
#define PRINTOUT 1
#define ASSERTIVE 0

int checkAdventurer(int adventurer, struct gameState *afterAdventurerState){
    struct gameState beforeAdventurerState;
    int returnVal;
    int i;
    int drawnTreasure = 0;
    int z = 0;
    int zcount;
    int shuffleCount = 0;
    int card;
    int treasure = 0;
    int drewTreasure = 0;
    int tempHand[MAX_HAND];
    int befHandCards;
    int afterHandCards;
    int afterDisCards;
    int befDisCards;
    int player = whoseTurn(afterAdventurerState);
    //copy so we can test if the Adventurer we can check
    memcpy(&beforeAdventurerState, afterAdventurerState, sizeof(struct gameState));
    
    //one thing we need to check before doing anything is making sure we have 2 treasures
    for(i = 0; i < beforeAdventurerState.deckCount[player]; i++){
	card = beforeAdventurerState.deck[player][i];
	//if the card is a treasure say so
	if(card == copper || card == silver || card == gold){
	    treasure++;
	}
	//only need to see if there are 2 or more
	if(treasure >= 2){
	    break;
	}
    }

    for(i = 0; i < beforeAdventurerState.discardCount[player]; i++){
	card = beforeAdventurerState.discard[player][i];
	//if the card is a treasure say so
	if(card == copper || card == silver || card == gold){
	    treasure++;
	}
	//only need to see if there are 2 or more
	if(treasure >= 2){
	    break;
	}
    }

    //if it is less than 2 though we should break
    if(treasure < 2){
	printf("We do not have 2 treasure cards, that would infinitely loop. Returning without testing\n");
	return 0;
    }
    
#if (PRINTOUT == 1)
    //check the number of hand and discards
    befDisCards = beforeAdventurerState.discardCount[player];
    befHandCards = beforeAdventurerState.handCount[player];
    afterDisCards = afterAdventurerState->discardCount[player];
    afterHandCards = afterAdventurerState->handCount[player];
#endif
    
    //do the Adventurer function card, choices, handpos, and bonus are unimportant hence 0's
    returnVal = cardEffect(adventurer, 0, 0, 0, afterAdventurerState, 0, 0 );
    
    while(drawnTreasure < 2){
	
#if (PRINTOUT == 1)
	if(beforeAdventurerState.deckCount[player] < 1){
	    printf("Deck was less than 1, shuffled 1 more time\n");
	}
#endif
	
	if(beforeAdventurerState.deckCount[player] < 1){
	    shuffle(player, &beforeAdventurerState);
	    //to see what we need to test
	    shuffleCount++;
	}
	//draw the card and keep track like in the card
	drawCard(player, &beforeAdventurerState);
	card = beforeAdventurerState.hand[player][beforeAdventurerState.handCount[player] - 1];
	
	if(card == copper || card == silver || card == gold){
	    drawnTreasure++;
	} else {
	    tempHand[z] = card;
	    beforeAdventurerState.handCount[player]--;
	    z++;
	}
    }
    
    //used to test discard
    zcount = z;

    while(z - 1 >= 0){
	beforeAdventurerState.discard[player][beforeAdventurerState.discardCount[player]++] = tempHand[z - 1];
	z = z - 1;
    }
    
    //I like the printout method more to see what the actual thing that happened is
#if (PRINTOUT == 1)
    //see if we shuffled any
    printf("We shuffled %d time(s), should be a print for each time we shuffled\n", shuffleCount);
    
    //handcount check
    //check the hand and discard cards could was correct
    if(befHandCards + 2 == beforeAdventurerState.handCount[player]){
	printf("The before village state hand count is correct\n");
    }else{
	printf("The before village state hand count is wrong %d %d \n", befHandCards, beforeAdventurerState.handCount[player]);
    }
    
    if(afterHandCards + 2 == afterAdventurerState->handCount[player]){
	printf("The after village state hand count is correct\n");
    }else{
	printf("The after village state hand count is wrong %d %d \n", afterHandCards, afterAdventurerState->handCount[player]);
    }
	
	//can check even if we shuffled
    //check that the last two in thehands are treasure cards
    if(beforeAdventurerState.hand[player][numHandCards(&beforeAdventurerState) - 1] < copper || beforeAdventurerState.hand[player][numHandCards(&beforeAdventurerState) - 1] > gold){
	printf("The before village state last card drawn isn't a treasure\n");
    }
    if(beforeAdventurerState.hand[player][numHandCards(&beforeAdventurerState) - 2] < copper || beforeAdventurerState.hand[player][numHandCards(&beforeAdventurerState) - 2] > gold){
	printf("The before village state 2nd to last card drawn isn't a treasure\n");
    }
    if(afterAdventurerState->hand[player][numHandCards(afterAdventurerState) - 1] < copper || afterAdventurerState->hand[player][numHandCards(afterAdventurerState) - 1] > gold){
	printf("The after village state last card drawn isn't a treasure\n");
    }
    if(afterAdventurerState->hand[player][numHandCards(afterAdventurerState) - 2] < copper || afterAdventurerState->hand[player][numHandCards(afterAdventurerState) - 2] > gold){
	printf("The after village state 2nd to last card drawn isn't a treasure\n");
    }
    

	
    //if we shuffled we cant test much so test only if we didnt shuffle (these ones at least)
    if(shuffleCount < 1){
	//if the draw card is the same then that part worked well 
	if(beforeAdventurerState.hand[player][numHandCards(&beforeAdventurerState) - 1] == afterAdventurerState->hand[player][numHandCards(afterAdventurerState) - 1]){
	    printf("The before adventurer state and after adventurer state have the same last card drawn, which is good\n");
	} else {
	    printf("The last card drawn is different before %d : after %d\n", beforeAdventurerState.hand[player][numHandCards(&beforeAdventurerState) - 1], afterAdventurerState->hand[player][numHandCards(afterAdventurerState) - 1]);
	}
	
	//if the 2nd to last draw card is the same then that part worked well 
	if(beforeAdventurerState.hand[player][numHandCards(&beforeAdventurerState) - 2] == afterAdventurerState->hand[player][numHandCards(afterAdventurerState) - 2]){
	    printf("The before adventurer state and after adventurer state have the same 2nd to last card drawn, which is good\n");
	} else {
	    printf("The 2nd to last card drawn is different before %d : after %d\n", beforeAdventurerState.hand[player][numHandCards(&beforeAdventurerState) - 2], afterAdventurerState->hand[player][numHandCards(afterAdventurerState) - 2]);
	}
	
	
	//only can check discards if we don't shuffle
	if(befDisCards + zcount == beforeAdventurerState.discardCount[player]){
	    printf("The before village state discard count is correct\n");
	}else{
	    printf("The before village state discard count is wrong %d %d z %d\n", befDisCards, beforeAdventurerState.discardCount[player], zcount);
	}
	if(afterDisCards + zcount == afterAdventurerState->discardCount[player]){
	    printf("The after village state discard count is correct\n");
	}else{
	    printf("The after village state discard count is wrong %d %d\n", afterDisCards, afterAdventurerState->discardCount[player]);
	}
	
	if(beforeAdventurerState.discardCount[player] == afterAdventurerState->discardCount[player]){
	    printf("The before adventurer state and after adventurer state have the same discard count, which is good\n\n");
	} else {
	    printf("The discard count is different before %d : after %d\n\n", beforeAdventurerState.discardCount[player], afterAdventurerState->discardCount[player]);
	}
	
    }
#endif

    return 0;
}


int main(){
    int i;
	int ranTimes;
    int player;
    //int numDeck;
    //int numDiscard;
    //int numHand;
    //int initialized;
    struct gameState theGameState;
    //int kingCards[10] = {adventurer, council_room, feast, gardens, mine, remodel, smithy, village, baron, salvager};

    srand(time(0));
    for (ranTimes = 0; ranTimes < 200; ranTimes++) {

	for (i = 0; i < sizeof(struct gameState); i++) {
	    ((char*)&theGameState)[i] = floor(rand() % 256);
	}
	
	printf("Test number: %d\n", ranTimes);
	
	//random player
	player = floor(rand() % 4);
	theGameState.whoseTurn = player;
	//random deck/discard/hand
	theGameState.deckCount[player] = floor(rand() % MAX_DECK);
	theGameState.discardCount[player] = floor(rand() % MAX_DECK);
	theGameState.handCount[player] = floor(rand() % MAX_HAND);
	
	//fill up the deck
	for(i = 0; i < theGameState.deckCount[player]; i++){
	    //set the deck to a specific card (only 27 cards so 0 to 27)
	    theGameState.deck[player][i] = floor(rand() % 27);
	}
	
	//fill up the hand, 
	for(i = 0; i < theGameState.handCount[player]; i++){
	    //set the deck to a specific card (only 27 cards so 0 to 27)
	    theGameState.hand[player][i] = floor(rand() % 27);
	}
	
	//fill up the discard, 
	for(i = 0; i < theGameState.discardCount[player]; i++){
	    //set the deck to a specific card (only 27 cards so 0 to 27)
	    theGameState.discard[player][i] = floor(rand() % 27);
	}

	checkAdventurer(adventurer, &theGameState);

	theGameState.deckCount[player] = 0;
	//checkAdventurer(adventurer, &theGameState);
    }
    
    return 0;
}
